﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WestWorldRemake.Messaging;

namespace WestWorldRemake.States
{
    public class StateMachine<T> where T : BaseGameEntity
    {
        private T m_pOwner;
        private State<T> m_pCurrentState;
        private State<T> m_pPreviousState;
        private State<T> m_pGlobalState;

        public StateMachine(T owner, State<T> DefaultGlobalState)
        {
            m_pOwner = owner;
            m_pCurrentState = null;
            m_pPreviousState = null;
            m_pGlobalState = DefaultGlobalState;

            ChangeState(m_pGlobalState);
        }
        public StateMachine(T owner, State<T> DefaultGlobalState, State<T> DefaultCurrentState)
        {
            m_pOwner = owner;
            m_pCurrentState = DefaultCurrentState;
            m_pPreviousState = null;
            m_pGlobalState = DefaultGlobalState;

            ChangeState(m_pCurrentState);
        }
        public State<T> CurrentState
        {
            get
            {
                return m_pCurrentState;
            }
        }
        public State<T> PreviousState
        {
            get
            {
                return m_pPreviousState;
            }
        }
        public State<T> GlobalState
        {
            get
            {
                return m_pGlobalState;
            }
        }

        public void Update()
        {
            if (m_pGlobalState != null) m_pGlobalState.Execute(m_pOwner);
            if (m_pCurrentState != null) m_pCurrentState.Execute(m_pOwner);
        }
        public Iffy HandleMessage(Telegram message)
        {
            Iffy result = Iffy.No;

            if (m_pCurrentState != null)
            {
                result = m_pCurrentState.OnMessage(m_pOwner, message);
            }
            if (m_pGlobalState != null)
            {
                result = m_pGlobalState.OnMessage(m_pOwner, message);
            }

            return result;
        }
        public void ChangeState(State<T> pNewState)
        {
            if (pNewState != null)
            {
                if (m_pCurrentState != null)
                {
                    m_pPreviousState = m_pCurrentState;
                    m_pCurrentState.Exit(m_pOwner);
                }
                m_pCurrentState = pNewState;
                m_pCurrentState.Enter(m_pOwner);
            }
        }
        public void RevertToPreviousState()
        {
            ChangeState(m_pPreviousState);
        }
        bool IsInState(State<T> state)
        {
            return (state.GetType() == m_pCurrentState.GetType());
        }
    }
}
